Sesión 6

Curso: Fundamentos R para Ciencia de Datos en Salud


Percy Soto-Becerra, M.D., M.Sc(c)

DIS – IETSI, EsSalud

2024-04-07

  https://github.com/psotob91

Medidas de resumen para variables numéricas

Agenda

  1. Medidas de resumen para variables numéricas

  2. Análisis descriptivo de variables categóricas

  3. Medidas de resumen de variables categóricas con R

  4. Gráficos de variables numéricas con R

  5. Gráficas de variables categóricas con R

  6. Gráfico de barras

  7. Otros gráficos

Análisis descriptivo de variable numérica

  • Medias de tendencia central
    • Media
    • Mediana (es también medida de posición)
    • Moda (no es usual)
  • Medidas de posición
    • Cuantiles (en general)
    • Mediana = percentil 50 (es también medida de tendencia central)
    • Percentil 25 (p25)
    • Percentil 75 (p75)
  • Medidas de dispersión
    • Rango (máximo - mínimo)
    • Varianza / Desviación estándar
    • Rango intercuartílico (p75 - p25)
  • De acuerdo a moda:
    • Unimodal (una sola moda)
    • Multimodal (p. ej, bimodal)
    • Uniforme (no moda)
  • De acuerdo a simetría
    • Simétrica
    • Asimétrica (o ‘sesgada’)
      • Positiva (A la derecha)
      • Negativa (A la izquierda)
  • De acuerdo a curtosis:
    • Leptocúrtica
    • Mesocúrtica
    • Platicúrtica



Medidas de resumen

Para una variable de interés \(X\), se tiene la muestra conformada por \(n\) elementos \(x_1, x_2, x_3, ..., x_n\) entonces podemos resumir esta muestra de valores mediante los siguientes estadísticos:

  • Media aritmética: \(\bar{x}\)

  • Media geométrica: \(\bar{x}_g\)

  • Otras medias: truncada y armónica

  • Mediana: \(Med(x)\)

  • Moda: \(Moda(x)\)

  • Percentiles: \(P25\) y \(P75\)

  • Cuartiles: \(Q1\), \(Q2\) y \(Q3\)

  • Varianza y desviación estándar: \(Var(x)\) y \(DE(x)\)

  • Rango

  • Rango intercuartílico: \(RIQ\)

  • Coeficiente de variación: \(CV\)

Medidas de resumen: Tendencia central

  • La media artimética de una lista de números, es la suma de estos números dividida por la cantidad de esto y está dada por la siguiente expresión:

\[\bar{x} = \frac{x_1 + x_2 + x_3 + ... + x_n}{n} = \frac{\sum_{i = 1}^{n}x_i}{n}\]

Ejemplo

Sean las siguientes edades en años: \(36, 4, 75, 45, 50\), su media aritmética es

\[\frac{36 + 4 + 75 + 45 + 50}{5} = \frac{210}{5} = 42\]

  • Forma de promedio útil para conjuntos de números positivos que se desean interpretar de acuerdo a su producto en vez de su suma.

  • Es la raíz \(n-ésima\) del producto de los números y está dada por la siguiente expresión:

\[\bar{x}_{g} = \sqrt[n]{x_1x_2x_3...x_n} = (x_1x_2x_3...x_n)^{\frac{1}{n}} = (\prod_{i = 1}^{n}x_i)^{\frac{1}{n}}\]

Ejemplo

Sean las siguientes edades en años: \(36, 4, 75, 45, 50\), su media geométrica es

\[(36 \times 4 \times 75 \times 45 \times 50) ^ {\frac{1}{5}} = \sqrt[5]{24300000} = 30\]

Media truncada

  • Media truncada o recortada (en inglés trimmed mean) es una medida de tendencia central similar a la media aritmética que se calcula luego de descartar las partes de ambos extremos de la distribución.

  • Típicamente se descartan las mismas proporcions de datos en los extremos.

  • En la mayoría de aplicaciones se descartan entre 5% a 25%.

  • En algunas regiones también la conocen como media windsoriana.

  • La usan mucho en eventos de competición para eliminar la influencia de las calificaciones extremas de los jueces

Media armónica

  • Es un tipo de medida promedio conocida por ser una de las medias pitagóricas.

  • Se expresa como el recíproco de las medias aritméticas de los recíprocos de un conjunto dado de observaciones.

\[H = \frac{n}{\frac{1}{x_1} + \frac{1}{x_2} + ... + \frac{1}{x_n}} = \frac{n}{\sum_{i=1}^{n}{\frac{1}{x_i}}} = (\frac{\sum_{i=1}^{n}x_i^{-1}}{n})^{-1} \] - Es más útil en situaciones donde se desea promediar tasas o estadístico similares basados en medidas de razón.

  • Sean \(x_{(1)}, x_{(2)}, x_{(3)}, ..., x_{(i)},..., x_{(n)}\) estadísticos de orden, es decir cada \(x_{(i)}\) representa al \(i-ésimo\) valor más pequeño de la muestra, entonces la mediana está dada por la siguiente expresión:

\[ Med(x) = \begin{cases} x_{(n+1)/2} & \text{si n es impar} \\ \frac{x_{(n/2)}+x_{(n/2+1)}}{2} & \text{si n es par} \end{cases} \]

Ejemplo

Luego de ordenar de menor a mayor, tenemos \(4, 36, 45, 50, 75\). Como \(n = 5\) es impar, entonces

\[Med(x) = x_{(5+1)/2} = x_{(3)} = 45\]

  • En otras palabras, es el valor que separa la mitad superior de la mitad inferior de una muestra de datos.

  • Es el valor que aparece más frecuentemente en los datos.

    • De poca utilidad en variables numéricas.
  • No necesariamente es única.


Unimodal

Multimodal

Multimodal extremo: Uniforme

  • En resumen, la visualización geométrica de la media, mediana y moda para una distribución unimodal es la siguiente.

    • Moda: Valor más frecuente (punta más alta de distribución)

    • Mediana: Valor que divide datos en 50% (mitad de la distribución)

    • Media: Centro de gravedad (punto en el que los “pesos” de ambos lados se igualan)

Funciones

  • Funciones de R base:

    • mean()

    • mean(…, trim = …)

    • median()

  • Funciones extras a R base:

    • geometric.mean() de {psych}

Datos para los cálculos

  • Sean el vector de edades:
edad <- c(9, 12, 10, 8, 7, 6)
edad
[1]  9 12 10  8  7  6
  • Sea el vector de hemoglobina:
hb <- c(11.2, 10.4, 9.8, NA, 14, 8.1)
hb
[1] 11.2 10.4  9.8   NA 14.0  8.1

Media aritmética

  • En vector con datos completos:
mean(edad)
[1] 8.666667
  • En vector con datos incompletos:
mean(hb)
[1] NA
  • Es necesario agregar na.rm = TRUE
mean(hb, na.rm = TRUE)
[1] 10.7

Media geométrica

  • Manualemente
exp(log(edad))
[1]  9 12 10  8  7  6
  • Con librería psych
library(psych)
geometric.mean(edad)
[1] 8.445535

Media truncada

  • Solo 5% de ambas colas
mean(edad, trim = 0.05)
[1] 8.666667

Mediana

median(hb, na.rm = TRUE)
[1] 10.4

Medidas de resumen: Posición

  • Son los valores que funcionana como puntos de corte para dividir el rango de datos en intervalos continuos con igual frecuencia.

  • El \(k-ésimo\) \(q-cuantil\) es el valor de los datos donde su función de distribución acumulada cruza \(k/q\).

  • Es decir, \(x\) es el \(k-ésimo\) \(q-cuantil\) para una variable \(X\) si:

\[Pr[X < x] \leq k/q\]

y

\[Pr[X \leq x] \geq k/q \]



  • El nombre del cuantil depende de cuántos grupos se forman.

  • La cantidad de cuantiles es siempre 1 menos.

    • Ejemplo, para formar 4 grupos, necesito solo 3 cortes: 3 cuartiles

  • Hay una lista bastante grande de cuantiles.

  • Los más famosos son:

    • Mediana
    • Terciles
    • Cuartiles
    • Quintiles
    • Deciles
    • Percentiles.
Q-cuantil Nombre del cuantil Número de grupos iguales Número de cuantiles
2-cuantil Mediana 2 1
3-cuantil Terciles 3 2
4-cuantil Cuartiles 4 3
5-cuantil Quintiles 5 4
6-cuantil Sextiles 6 5
7-cuantil Septiles 7 6
8-cuantil Octiles 8 7
10-cuantil Deciles 10 9
12-cuantil Dodeciles 12 11
16-cuantil Hexadeciles 16 15
20-cuantil Ventiles 20 19
100-cuantil Percentiles 100 99
1000-cuantil Permiles o Mililes 1000 999
  • Los cuartiles dividen los datos en cuatro partes iguales

    • Por lo tanto, hay 3 cuartiles.
  • Los gráficos de cajas utilizan los cuartiles para realizar el dibujo de los elementos de la caja.

    • El segundo cuartil es equivalente a la mediana porque contiene el 50% de los datos.

  • Los percentiles dividen los datos en 100 partes iguales

    • Por lo tanto, son 99 percentiles.
  • Se usan para construir infinidad de estadísticos:

    • Tablas de crecimiento, ranking de calificaciones, etc.
  • En inferencia estadística, se usan para establecer

    • Nivel de confianza
    • Nivel de significancia.


Funciones

  • Funciones de R base:

    • quantile(…, probs = …)

Datos para los cálculos

  • Sean el vector de edades:
edad <- c(9, 12, 10, 8, 7, 6)
edad
[1]  9 12 10  8  7  6
  • Sea el vector de hemoglobina:
hb <- c(11.2, 10.4, 9.8, NA, 14, 8.1)
hb
[1] 11.2 10.4  9.8   NA 14.0  8.1

Cuartiles

  • Cuartil 1 (25%)
quantile(edad, probs = c(0.25))
 25% 
7.25 
  • Cuartil 3 (75%)
quantile(edad, probs = c(0.75))
 75% 
9.75 
  • Cuartiles 1, 2 y 3
quantile(edad, probs = c(0.25, 0.5, 0.75))
 25%  50%  75% 
7.25 8.50 9.75 

Percentiles

  • Percentil 67
quantile(edad, probs = c(0.67))
 67% 
9.35 
  • Percentiles del 1 al 99
quantile(edad, probs = seq(0, 0.99, 0.01))
   0%    1%    2%    3%    4%    5%    6%    7%    8%    9%   10%   11%   12% 
 6.00  6.05  6.10  6.15  6.20  6.25  6.30  6.35  6.40  6.45  6.50  6.55  6.60 
  13%   14%   15%   16%   17%   18%   19%   20%   21%   22%   23%   24%   25% 
 6.65  6.70  6.75  6.80  6.85  6.90  6.95  7.00  7.05  7.10  7.15  7.20  7.25 
  26%   27%   28%   29%   30%   31%   32%   33%   34%   35%   36%   37%   38% 
 7.30  7.35  7.40  7.45  7.50  7.55  7.60  7.65  7.70  7.75  7.80  7.85  7.90 
  39%   40%   41%   42%   43%   44%   45%   46%   47%   48%   49%   50%   51% 
 7.95  8.00  8.05  8.10  8.15  8.20  8.25  8.30  8.35  8.40  8.45  8.50  8.55 
  52%   53%   54%   55%   56%   57%   58%   59%   60%   61%   62%   63%   64% 
 8.60  8.65  8.70  8.75  8.80  8.85  8.90  8.95  9.00  9.05  9.10  9.15  9.20 
  65%   66%   67%   68%   69%   70%   71%   72%   73%   74%   75%   76%   77% 
 9.25  9.30  9.35  9.40  9.45  9.50  9.55  9.60  9.65  9.70  9.75  9.80  9.85 
  78%   79%   80%   81%   82%   83%   84%   85%   86%   87%   88%   89%   90% 
 9.90  9.95 10.00 10.10 10.20 10.30 10.40 10.50 10.60 10.70 10.80 10.90 11.00 
  91%   92%   93%   94%   95%   96%   97%   98%   99% 
11.10 11.20 11.30 11.40 11.50 11.60 11.70 11.80 11.90 

Medidas de resumen: Dispersión

  • Medida de la cantidad de variación o dispersión de los datos.

    • Mide dispersión según alejamiento de la media.
  • Es la raíz cuadrada de la varianza.

  • Está en las mismas unidades que la variable.

  • Fórmula:

Sea \(\bar{x}\) la media de los \(n\) datos \(x_1, x_2, ..., x_n\), entonces la varianza está definida por:

\[Var(x) = \frac{\sum_{i = 1}^{n}{(x_i - \bar{x})^2}}{n - 1} \] Entonces, la desviación estándar de la muestra es:

\[ DE(x) = \sqrt[]{Var(x)} \]

Varianza muestral

  • Con datos completos:
var(edad)
[1] 4.666667
  • Con datos perdidos:
var(hb, na.rm = TRUE)
[1] 4.7

Desviación estándar muestral

  • Con datos completos:
sd(edad)
[1] 2.160247
  • Con datos faltantes:
sd(hb, na.rm = TRUE)
[1] 2.167948
  • Es el tamaño del intervalo más pequeño que contiene a todos los datos.

  • Diferencia entre el valor mínimo y máximo.

  • Fórmula

\[ Rango = min(X) - max(X) \]

Manualmente

  • Con datos completos:
min(edad)
[1] 6
max(edad)
[1] 12
max(edad) - min(edad)
[1] 6

Usando función

  • Con datos completos:
range(edad)
[1]  6 12
  • Con datos faltantes:
range(hb, na.rm = TRUE)
[1]  8.1 14.0
  • Medida de la cantidad de variación de los datos.

  • Es la diferencia entre los percentiles 75 y 25 de los datos.

  • Contiene el 50% central de los datos.

  • El ancho de la caja de un gráfico de cajas es el IQR.

  • Fórmula:

\[ RIQ = Percentil~75 - Percentil~25 \]

Manualmente

  • Calculándolo manualmente
quantile(edad, probs = c(0.25, 0.75))
 25%  75% 
7.25 9.75 
9.75 - 7.25
[1] 2.5
  • Usando algunos atajos:

Podemos almacenar los resultados en objetos

p25 <- quantile(edad, probs = c(0.25))
p25
 25% 
7.25 
p75 <- quantile(edad, probs = c(0.75))
p75
 75% 
9.75 

Luego podemos usar los objetos par hacer el cálculo final:

p75 - p25
75% 
2.5 

Usando función

  • Con datos completos:
IQR(edad)
[1] 2.5
  • Con datos faltantes:
IQR(hb, na.rm = TRUE)
[1] 1.4
  • También conocido como desviación estándar relativa.

  • Medida estandarizada de dispersión expresada como porcentaje.

  • Es la razón de la desviación estandar sobre la media y mide la extensión de la variabilidad en relación a la media

\[ CV = \frac{DE(x)}{\bar{x}} \]

Manualmente

  • Directo
100 * sd(edad) / mean(edad)
[1] 24.92593
  • Paso a paso

Media:

media <- mean(edad)

DE:

sd <- sd(edad)

CV en %

100 * (sd / media)
[1] 24.92593

Usando función

  • No función específica disponible.

  • Existe en funciones que generan varias variables de resumen.

Análisis descriptivo de variable numérica - recomendaciones

  • Media y mediana no son dos medidas que deban entrar en disputa.

    • Ambas cuentan dos historias complementarias sobre el “centro” de los datos.

    • Ambas representan a los datos a su manera.

  • Piensa en lo que quieres hacer

¿Quiero describir mis datos con el “mejor representante” posible?

  • Recuerda el mantra: "Media es más sensible a valores extremos". La distribución de los datos puede ayudar a elegir.

  • Distribuciones sesgadas: La mediana y medidas de posición suelen representar mejor los datos en términos descriptivos.

  • Distribuciones simétricas: Mediana y media son buenas, la media se prefiere por sus propiedades estadísticas e interpretación intuitiva.

¿Quiero comparar medidas de tendencia central para inferir efectos?

  • La media es una buena candidata, sean las distribuciones sesgadas o no.

  • La mediana no es una mala candidata, sin embargo, sus propiedades estadísticas y menor teoría desarrollada limitan actualmente su uso.

¿Quiero usar una medida de resumen para establecer predicciones?

  • La media es una de las más usadas, sean las distribuciones sesgadas o no.

  • La mediana tiene teoría menos desarrollada, pero existen algunas aplicaciones.

  • ¿Tenemos que elegir?
                    No, no tenemos que elegir!!
  • En ensayos clínicos es preferible reportar ambos es más transparente y proporciona más información.

    • Si hay limitaciones de espacio y tablas en cuerpo del artículo, se suele reportar en anexos.
    • Se sugiere hacer lo mismo en estudios observacionales.
    • ¿Por qué no? ¡Todas las revistas permiten anexos! No hay excusas.
  • Tengo limitaciones de espacio y debo elegir una medida en la tabla principal:

    • Elige la opción que mejor se adecue a tu objetivo: describir, explicar, predecir.

    • RECUERDA: Pon en anexos las demás medidas. Es información que podría ser útil para otros fines (p. ej., para calcular tamaño de muestra, evaluar comparabilidad de poblaciones, etc.)

Si objetivo es DESCRIBIR

  • Siempre reporte máximo y mínimo, preferentemente en tabla principal o texto.

    • Es mejor que rango, provee más información.

    • Si problemas de espacio, usar tabla anexa.

  • Media +/- Desviación estándar

    • Cuando meta es describir y la distribución es simétrica y variabilidad es relativamente baja.
    • La distribución normal es un ejemplo de distribución simétrica.
  • Mediana (percentil 25 - percentil 75)

    • Cuando meta es describir y la distribución es asimétrica o variabilidad es relativamente alta.
    • Mejor percentiles 25 y 75 en vez de rango intercuartílico (más informaciónde los primeros)

Análisis de varias variables numéricas

  • Hay varias opciones en R.

  • Las más personalizables se basan en {R base} y {dplyr} (funciones summarise()), pero requieren más código.

    • Usar estas si se necesitan elaborar tablas ad hoc para reportes repropducibles muy sui generis.

    • También son necesarias para gráficos en {ggplot2}

  • Las opciones que requieren poco código y son directas tienen el problema de que no son personalizables:

    • {summarytools}

    • {DescTools}

    • {Hmisc}

    • Usar estas si solo se requiere inspeccionar los datos pero no se hará ningún reporte reproducibl sui generis.

  • El problema con R base es que solo permite generar medidas de resumen una a la vez.

  • Cuando inspeccionamos datos o los describimos necesitamos hacerlo con varias variables simultáneamnente.

  • Podemos hacerlo con otras funciones de R.

  • Hay muchas opciones, veremos algunas que se sustentan en R tidy

  • Podemos usar la función summarise() para solicitar estadísticos de resumen. Se requiere llamar las funciones de R base para medidas de resumen.

Sin etiquetado

bd_inmuno %>% 
  summarise(mean(edad))
  mean(edad)
1   48.24561

Mejor con etiquetado

bd_inmuno %>% 
  summarise(Media = mean(edad))
     Media
1 48.24561

Varios estadísticos pueden obtenerse

bd_inmuno %>% 
  summarise(
    Media = mean(edad), 
    DE = sd(edad), 
    Mediana = median(edad), 
    `Percentil 25` = quantile(edad, 0.25), 
    `Percentil 75` = quantile(edad, 0.75) 
    )
     Media       DE Mediana Percentil 25 Percentil 75
1 48.24561 14.70901      46           36           59

Varias variables pueden analizarse

bd_inmuno %>% 
  summarise(
    `Media de edad` = mean(edad), 
    `DE de edad` = sd(edad), 
    `Mediana de edad` = median(edad),
    Mediana_IgG_Final = median(IgG_Basal, na.rm = TRUE), 
    RIQ_IgG_Final = IQR(IgG_Basal, na.rm = TRUE)
    )
  Media de edad DE de edad Mediana de edad Mediana_IgG_Final RIQ_IgG_Final
1      48.24561   14.70901              46            28.325         88.17
  • Genera un resumen descriptivo bastante detallado de las variables numéricas.
library(summarytools)
  • La función que describe variables numéricas es descr()

Una sola variable numérica

bd_inmuno %>% 
  descr(edad)
Descriptive Statistics  
bd_inmuno$edad  
Label: edad  
N: 285  

                      edad
----------------- --------
             Mean    48.25
          Std.Dev    14.71
              Min    23.00
               Q1    36.00
           Median    46.00
               Q3    59.00
              Max    97.00
              MAD    17.79
              IQR    23.00
               CV     0.30
         Skewness     0.44
      SE.Skewness     0.14
         Kurtosis    -0.39
          N.Valid   285.00
        Pct.Valid   100.00

Todas las variables numéricas

bd_inmuno %>% 
  descr()
Descriptive Statistics  
bd_inmuno  
N: 285  

                      edad       id   IgG_Basal   IgG_Final   tdosis_refuerzo
----------------- -------- -------- ----------- ----------- -----------------
             Mean    48.25   143.00       82.54      492.26            214.47
          Std.Dev    14.71    82.42      122.33       71.15             25.28
              Min    23.00     1.00       -2.19      235.51            134.00
               Q1    36.00    72.00        8.13      447.18            199.00
           Median    46.00   143.00       28.33      501.20            222.00
               Q3    59.00   214.00       96.61      545.15            235.00
              Max    97.00   285.00      583.97      618.44            267.00
              MAD    17.79   105.26       36.80       70.13             22.24
              IQR    23.00   142.00       88.17       97.97             36.00
               CV     0.30     0.58        1.48        0.14              0.12
         Skewness     0.44     0.00        2.14       -0.73             -0.87
      SE.Skewness     0.14     0.14        0.14        0.14              0.14
         Kurtosis    -0.39    -1.21        3.92        0.44             -0.08
          N.Valid   285.00   285.00      284.00      285.00            285.00
        Pct.Valid   100.00   100.00       99.65      100.00            100.00

Solo algunas variables numéricas

bd_inmuno %>% 
  select(edad, IgG_Basal) %>% 
  descr()
Descriptive Statistics  
bd_inmuno  
N: 285  

                      edad   IgG_Basal
----------------- -------- -----------
             Mean    48.25       82.54
          Std.Dev    14.71      122.33
              Min    23.00       -2.19
               Q1    36.00        8.13
           Median    46.00       28.33
               Q3    59.00       96.61
              Max    97.00      583.97
              MAD    17.79       36.80
              IQR    23.00       88.17
               CV     0.30        1.48
         Skewness     0.44        2.14
      SE.Skewness     0.14        0.14
         Kurtosis    -0.39        3.92
          N.Valid   285.00      284.00
        Pct.Valid   100.00       99.65

Solo algunos estadísticos

bd_inmuno %>% 
  descr(edad, 
        stats = c("mean", "sd", "min", "max"))
Descriptive Statistics  
bd_inmuno$edad  
Label: edad  
N: 285  

                 edad
------------- -------
         Mean   48.25
      Std.Dev   14.71
          Min   23.00
          Max   97.00
  • El paquete {Hmisc} genera un reporte de resultados similar al de summarytools.
library(Hmisc)
  • La función describe() del paquete {Hmisc} genera un reporte con los principales estadísticos de resumen:

Modo R base

describe(bd_inmuno$edad)
   vars   n  mean    sd median trimmed   mad min max range skew kurtosis   se
X1    1 285 48.25 14.71     46   47.55 17.79  23  97    74 0.44    -0.39 0.87

Modo R tidy

bd_inmuno %>% 
  pull(edad) %>% 
  describe()
   vars   n  mean    sd median trimmed   mad min max range skew kurtosis   se
X1    1 285 48.25 14.71     46   47.55 17.79  23  97    74 0.44    -0.39 0.87

¿Cómo interpretar ….

  • La media aritmética es una medida que trata de resumir los datos de una variable numérica en un solo valor.

    • La idea de la media es que este valor represente o sea el delegado de todos los datos.
    • Podemos pensar la media como el valor más probable que tendría cada individuo si no supieramos qué valores realmente tienen: “si no sabes qué valor tiene, apuesta por el promedio”.
  • Propiedad interesante: Es la medida que más cerca está de todos los datos.

    • En promedio, el desvío de la media respecto a los datos es nulo.
  • En la práctica, solo se reporta como promedio, sin más interpretación (esta es tácita).
       “La edad media fue de 34 años (…)”

Ejemplo

  • Tenemos cuatro notas del curso de Bioestadística: 15, 20, 17 y 12.
  • El promedio de estas notas es 16.

  • Cada nota se desvía del promedio en lo siguiente:

notas promedio_notas desvio_notas desvio_promedio
15 16 -1 0
20 16 4 0
17 16 1 0
12 16 -4 0

Mediana

  • Puede dejarse tácita la interpretación (lo más común):
         “La mediana de edad fue de 35 años (…)”
  • Como representa el 50% de los datos, también puede interpretarse como (para enfatizar un hallazgo relevante):
         “La mitad de los participantes tuvieron niveles de
         hemoglobina por debajo de 10.2 mg/dl (…)“

Percentiles 25 y 75

  • Puede dejarse tácita la interpretación (lo más común):
         “La mediana de edad fue de 35 años
         (20 años - 54 años) (…)“
  • Como representan % conocidos, también puede interpretarse como (para enfatizar un hallazgo relevante):
         “El 25% de los participantes tuvieron menos de 20
         años y el 75% menos de 54 años (…)“

Varianza

  • No se suele interpertar.

  • Debido a que está en unidades al cuadrado no se suele reportar, se prefiere a la desviación estándar.

Desviación estándar

  • No se suele interpretar, solo reportar.

  • Lo que implica que su interpretación/significado es tácito.

  • Es la medida de dispersión que acompaña por defecto a la media:

         “La edad media (desviación estándar) fue de 35
         años (23 años) (…)“

Rango

  • Es preferible reportar los valores mínimo y máximo.

  • A menudo se parafrasea:

         “La edad media (desviación estándar) fue de 35
         años (23 años) y varió entre 19 y 54 años (…)“

Rango intercuartílico

  • Es preferible reportar el percentil 25 y 75, no la diferencia: Da más información.

  • Se parafrasea como el ejemplo de los percentiles 25 y 75.

  • También se puede parafrasear de la siguiente manera:

         “La mediana de edad fue de 35 años
         y la mitad de los participantes tuvo
         entre 20 años y 54 años (…)“

Coeficiente de variación

  • Cuando se reporta, no se suele interpretar (es tácito).

  • Sin embargo, podemos hacer una valoración ‘cualitativa’ del valor para algun interpretación.

  • Algunas reglas del pulgar (según INEI, Perú):

    • \(CV < 5\%\) : Poca variabilidad
    • \(5\% \leq CV \leq 10\%\): Variabilidad regular
    • \(CV > 10\%\): Alta variabilidad (aquí podría ser mejor describir usando medidas de posición)

Análisis descriptivo de variables categóricas

Agenda

  1. Medidas de resumen para variables numéricas

  2. Análisis descriptivo de variables categóricas

  3. Medidas de resumen de variables categóricas con R

  4. Gráficos de variables numéricas con R

  5. Gráficas de variables categóricas con R

  6. Gráfico de barras

  7. Otros gráficos

Medidas de frecuencia

¿Qué describir de los datos categóricos?

  • Frecuencia absoluta

  • Frecuencia relativa

    • Proporción

      • Entre 0 y 1
    • Porcentaje

      • Entre 0% y 100% = Proporción * 100 %

El tamaño importa

  • Si n es pequeño (< 100, habitualmente)

    • Mejor solo reportar frecuencias absolutas.

    • Porcentajes pueden ser contraintuitivos.

  • Si n es mayor que 100

    • Frecuencias absolutas + relativas (en %, a menudo).

Algunos proporciones tienen nombres propios

  • Frecuencias relativas de eventos de interés (problemas de salud, estados de salud, enfermedades, etc.) suelen tener nombres específicas en Epidemiología Clínica y Bioestadística.

  • El nombre depende de cómo se construye la proporción.

    • Prevalencia
    • Incidencia Acumulada o Proporción de Incidencia
    • Odds
      • Prevalente
      • Incidente
  • Algunos diseños de estudio permiten su cálculo, otros, los vuelven imposibles.

Frecuencias Relativas en Bioestadística y Epi Clínica

Proporción de una población específica que está afectada por un evento de salud de interés (típicamente una enfermedad o factor de riesgo, pero también puede ser factor benéfico) en un tiempo específico.

\[Prevalencia = \frac{\text{Nº de eventos en t}}{\text{Nº de eventos + Nº sin evento en t}}\]

  • El tiempo específico puede ser un punto, un periodo o toda una vida.

  • Puede calcularse en una muestra cualquiera, pero a menudo interesan prevalencias de poblaciones relevantes.

    • Hablaremos de esto mejor en la sección de estimación.
  • Tipos de prevalencia: Dependen de qué es \(t\)
    • Prevalencia puntual: \(t\) es solo un momento.
    • Prevalencia de intervalo: \(t\) es un intervalo definido de tiempo.
    • Prevalencia de vida: \(t\) es todo el intervalo de la vida del sujeto (desde que ocurrió alguna vez el evento).

Proporción de incidencia o incidencia acumulada es la probabilidad de que ocurra un nuevo evento particular (tal como una enfermedad) antes de un tiempo dado.

  • El cáculo es directo si no han habido pérdidas en el seguimiento de los individuos y la fórmula es la siguiente:

\[ \text{Incidencia Acumulada} = \frac{\text{Nº eventos nuevos durante periodo t}}{\text{Nº de individuos sin evento en risgo al inicio del periodo t}} \]

  • El cálculo no es directo si hay pérdidas de seguimiento (lo conversaremos en otra clase).

Prevalencia versus Incidencia Acumulada

Prevalencia Incidencia Acumulada
Numerador Eventos existentes en t Eventos nuevos durante el periodo t
Denominador Todos los individuos (con y sin eventos) en t Individuos sin evento al inicio del periodo t
¿Probabilidad de qué...? Probabilidad de tener el evento Probabilidad de desarrolalr evento nuevo
Notas Solo requiere un punto en el tiempo. A menudo se busca poblaciones relevantes y usa muestras probabilísticas. Requiere al menos dos puntos de tiempo. Puede estimarse en poblaciones relevantes. A menudo se usan muestras no probabilísticas en las que es factible el seguimiento (p. ej., pacientes)

Es la razón de la probabilidad del evento entre la probabilidad del no evento.

\[Odds = \frac{Pr(evento)}{Pr(\text{no evento})} = \frac{Pr(evento)}{1 - Pr(\text{evento})}\]

  • Es solo una forma diferente de escribir la probabilidad del evento.

    • Análogo a expresar en céntimos y no en soles el precio de algo.
    • Por tanto, es una forma diferente de expresar lo mismo:
      • La frecuencia relativa de un evento y, a través de esta, su incertidumbre asociada.
  • Si probabilidad de ganar es de 0.8 (~80%), entonces el odds es 4. El odds se interpretaría como:
                    La probabilidad de ganar es 4
                  veces la probabilidad de perder.
  • Odds y probabilidad son diferentes, pero tienen valores muy similares cuando la probabilidad del evento es muy pequeña.
Probabilidad Odds Diferencia
0.000 0.0000000 0.0000000
0.010 0.0101010 0.0001010
0.020 0.0204082 0.0004082
0.030 0.0309278 0.0009278
0.040 0.0416667 0.0016667
0.050 0.0526316 0.0026316
0.100 0.1111111 0.0111111
0.200 0.2500000 0.0500000
0.300 0.4285714 0.1285714
0.400 0.6666667 0.2666667
0.500 1.0000000 0.5000000
0.800 4.0000000 3.2000000
0.900 9.0000000 8.1000000
0.990 99.0000000 98.0100000
0.999 999.0000000 998.0010000



  • Los odds no se usan mucho en epidemiología para expresar frecuencias; pero una medida derivada de esta sí se usa mucho para expresar asociación: la razón de odds (OR).

  • En epidemiología, las proporciones o probabilidades puede ser incidencias acumuladas o prevalencias, por lo que tenemos dos tipos de Odds:

Odds prevalente

\[Odds_{Prevalente} = \frac{Prevalencia}{1 - Prevalencia}\]

Odds incidente

\[Odds_{Incidente} = \frac{\text{Incidencia Acumulada}}{1 - \text{Incidencia Acumulada}}\]

Medidas de resumen de variables categóricas con R

Agenda

  1. Medidas de resumen para variables numéricas

  2. Análisis descriptivo de variables categóricas

  3. Medidas de resumen de variables categóricas con R

  4. Gráficos de variables numéricas con R

  5. Gráficas de variables categóricas con R

  6. Gráfico de barras

  7. Otros gráficos

Análisis con R

  • Hay varias opciones en R.

  • Las más personalizables se basan en {dplyr} y {janitor} (funciones summarise()), pero requieren más código.

    • Usar estas si se necesitan elaborar tablas ad hoc para reportes repropducibles muy sui generis.

    • También son necesarias para gráficos en {ggplot2}

  • Las opciones que requieren poco código y son directas tienen el problema de que no son personalizables:

    • {summarytools}

    • {DescTools}

    • Usar estas si solo se requiere inspeccionar los datos pero no se hará ningún reporte reproducibl sui generis.

La función table() y prop.table()es la más usada. Sin embargo, genera tablas “sucias” que requieren mucho código para personalizarse.

  • Tabla de frecuencias absolutas
table(bd_inmuno$sexo)

 Femenino Masculino 
      189        95 
  • Tabla de frecuencias relativas
prop.table(table(bd_inmuno$sexo))

 Femenino Masculino 
 0.665493  0.334507 
  • Tabla de frecuencias incluyendo los datos faltantes
table(bd_inmuno$sexo, useNA = "always")

 Femenino Masculino      <NA> 
      189        95         1 

Podemos combinar la funcion group_by() con summarise() para generar una tabla de frecuencias de la variable de interés. Podemos también tomar un atajo con count

  • Frecuencias absolutas: Forma larga
bd_inmuno %>% 
  group_by(sexo) %>% 
  summarise(n = n())
# A tibble: 3 × 2
  sexo          n
  <fct>     <int>
1 Femenino    189
2 Masculino    95
3 <NA>          1
  • Frecuencias absolutas + relativas: Forma larga
library(scales) # Para agregar escalas, p. ej., porcentajes %
bd_inmuno %>% 
  group_by(sexo) %>% 
  summarise(n = n()) %>% 
  mutate(
    Porcentaje = scales::percent(n / sum(n))
  )
# A tibble: 3 × 3
  sexo          n Porcentaje
  <fct>     <int> <chr>     
1 Femenino    189 66%       
2 Masculino    95 33%       
3 <NA>          1 0%        
  • Frecuencias absolutas: Atajo con count()
bd_inmuno %>% 
  count(sexo)
# A tibble: 3 × 2
  sexo          n
  <fct>     <int>
1 Femenino    189
2 Masculino    95
3 <NA>          1
  • Frecuencias absolutas + relativas: Atajo con count()
library(scales) # Para agregar escalas, p. ej., porcentajes %
bd_inmuno %>% 
  count(sexo) %>% 
  mutate(
    Porcentaje = scales::percent(n / sum(n))
  )
# A tibble: 3 × 3
  sexo          n Porcentaje
  <fct>     <int> <chr>     
1 Femenino    189 66%       
2 Masculino    95 33%       
3 <NA>          1 0%        

El paquete {janitor}, a través de su función [tabyl(){.verde-h3}], ofrece atajos y funciones pre-definidas para realizar tablas basadas en funciones de {dplyr}.

  • {janitor} ejecuta internamente summarise(), group_by() y otras funciones más, simplificando notoriamente el código.
  • Hay que instalar el paquete {janitor} y luego cargarlo
library(janitor)

Tabla simple generada por tabyl()

bd_inmuno %>% 
  tabyl(sexo)
      sexo   n     percent valid_percent
  Femenino 189 0.663157895      0.665493
 Masculino  95 0.333333333      0.334507
      <NA>   1 0.003508772            NA

Puedes “adornar” la tabla usando más funciones de {janitor}

Cambiar formato de porcentaje a %

bd_inmuno %>% 
  tabyl(sexo, show_na = FALSE) %>% 
  adorn_pct_formatting()
      sexo   n percent
  Femenino 189   66.5%
 Masculino  95   33.5%
  • Puedes suprimir los datos perdidos
bd_inmuno %>% 
  tabyl(sexo, show_na = FALSE)
      sexo   n  percent
  Femenino 189 0.665493
 Masculino  95 0.334507

Agregar totales

bd_inmuno %>% 
  tabyl(sexo, show_na = FALSE) %>% 
  adorn_pct_formatting() %>% 
  adorn_totals()
      sexo   n percent
  Femenino 189   66.5%
 Masculino  95   33.5%
     Total 284       -

Configurar precisión decimal

bd_inmuno %>% 
  tabyl(sexo, show_na = FALSE) %>% 
  adorn_pct_formatting(digits = 2) %>% 
  adorn_totals() 
      sexo   n percent
  Femenino 189  66.55%
 Masculino  95  33.45%
     Total 284       -

Si queremos una evaluación rápida de varias variables puede ser obtenida usando la función freq() del paquete {summarytools}

  • Una sola variable:
bd_inmuno %>% 
  select(sexo) %>% 
  freq()
Frequencies  
bd_inmuno$sexo  
Label: genero  
Type: Factor  

                  Freq   % Valid   % Valid Cum.   % Total   % Total Cum.
--------------- ------ --------- -------------- --------- --------------
       Femenino    189     66.55          66.55     66.32          66.32
      Masculino     95     33.45         100.00     33.33          99.65
           <NA>      1                               0.35         100.00
          Total    285    100.00         100.00    100.00         100.00
  • Solo las seleccioandas
bd_inmuno %>% 
  select(sexo, comorb) %>% 
  freq()
Frequencies  
bd_inmuno$sexo  
Label: genero  
Type: Factor  

                  Freq   % Valid   % Valid Cum.   % Total   % Total Cum.
--------------- ------ --------- -------------- --------- --------------
       Femenino    189     66.55          66.55     66.32          66.32
      Masculino     95     33.45         100.00     33.33          99.65
           <NA>      1                               0.35         100.00
          Total    285    100.00         100.00    100.00         100.00

bd_inmuno$comorb  
Label: comorbilidad  
Type: Factor  

              Freq   % Valid   % Valid Cum.   % Total   % Total Cum.
----------- ------ --------- -------------- --------- --------------
         No    214     75.09          75.09     75.09          75.09
         Sí     71     24.91         100.00     24.91         100.00
       <NA>      0                               0.00         100.00
      Total    285    100.00         100.00    100.00         100.00
  • Todas las variables categóricas
bd_inmuno %>% 
   freq()
Frequencies  
bd_inmuno$sexo  
Label: genero  
Type: Factor  

                  Freq   % Valid   % Valid Cum.   % Total   % Total Cum.
--------------- ------ --------- -------------- --------- --------------
       Femenino    189     66.55          66.55     66.32          66.32
      Masculino     95     33.45         100.00     33.33          99.65
           <NA>      1                               0.35         100.00
          Total    285    100.00         100.00    100.00         100.00

bd_inmuno$comorb  
Label: comorbilidad  
Type: Factor  

              Freq   % Valid   % Valid Cum.   % Total   % Total Cum.
----------- ------ --------- -------------- --------- --------------
         No    214     75.09          75.09     75.09          75.09
         Sí     71     24.91         100.00     24.91         100.00
       <NA>      0                               0.00         100.00
      Total    285    100.00         100.00    100.00         100.00

bd_inmuno$tipo_refuerzo  
Label: tipo_refuerzo  
Type: Character  

                       Freq   % Valid   % Valid Cum.   % Total   % Total Cum.
-------------------- ------ --------- -------------- --------- --------------
      (Empty string)      1      0.35           0.35      0.35           0.35
          Heterologo    228     80.00          80.35     80.00          80.35
            Homologo     56     19.65         100.00     19.65         100.00
                <NA>      0                               0.00         100.00
               Total    285    100.00         100.00    100.00         100.00

bd_inmuno$ant_COV  
Label: ant_COV  
Type: Factor  

                        Freq   % Valid   % Valid Cum.   % Total   % Total Cum.
--------------------- ------ --------- -------------- --------- --------------
         No Infection    201     70.53          70.53     70.53          70.53
      Prior Infection     84     29.47         100.00     29.47         100.00
                 <NA>      0                               0.00         100.00
                Total    285    100.00         100.00    100.00         100.00
  • Eliminando los datos perdidos y otras caracteristicas:
bd_inmuno %>% 
   freq(report.nas = FALSE, 
        totals = FALSE,
        cumul = FALSE, 
        headings= FALSE)
bd_inmuno$sexo  

                  Freq       %
--------------- ------ -------
       Femenino    189   66.55
      Masculino     95   33.45

bd_inmuno$comorb  

           Freq       %
-------- ------ -------
      No    214   75.09
      Sí     71   24.91

bd_inmuno$tipo_refuerzo  

                       Freq       %
-------------------- ------ -------
      (Empty string)      1    0.35
          Heterologo    228   80.00
            Homologo     56   19.65

bd_inmuno$ant_COV  

                        Freq       %
--------------------- ------ -------
         No Infection    201   70.53
      Prior Infection     84   29.47

Análisis descriptivo de variable categórica - recomendaciones

  • Se estila reportar los resultados como números en tablas.

  • En el texto, se puede resaltar los resultados de una o más variables de interés.

  • Un ejemplo de esto sería:

bd_inmuno %>% 
  select(sexo, ant_COV) %>% 
   freq(report.nas = FALSE, 
        totals = FALSE,
        cumul = FALSE, 
        headings= FALSE)
bd_inmuno$sexo  

                  Freq       %
--------------- ------ -------
       Femenino    189   66.55
      Masculino     95   33.45

bd_inmuno$ant_COV  

                        Freq       %
--------------------- ------ -------
         No Infection    201   70.53
      Prior Infection     84   29.47
  • Interpretación tentativa para sexo:
        “El 66.6% de los participantes fueron mujeres. (…)”
  • Algunos sugieren agregar la información de las frecuencias absolutas:
        “El 66.6% (189 / 284) de los participantes fueron
        mujeres. (…)“
  • Para el caso de eventos de salud, se estila usar los términos prevalencia o incidencia acumulada si el diseño lo permite. Por tanto, una interpretación tentativa para antecedente de infección por COVID-19:
       “La prevalencia de antecedente de infección previa por
       COVID-19 fue de 29.47% (84 / 285). (…)“

Gráficos de variables numéricas con R

Agenda

  1. Medidas de resumen para variables numéricas

  2. Análisis descriptivo de variables categóricas

  3. Medidas de resumen de variables categóricas con R

  4. Gráficos de variables numéricas con R

  5. Gráficas de variables categóricas con R

  6. Gráfico de barras

  7. Otros gráficos

Intro sobre gráficos de variables numéricas


  • Permiten visualizar la distribución de la variable numérica en la muestra de datos.

  • Hay varios tipos de gráficos que pueden hacerse para inspeccionar la variable numérica.

  • Hay que distinguir dos tipos de gráficos:

    • Los de inspección: Deben ser rápidos de generar y leer, aunque no sean tan personalizables o elegantes. Usar funciones wrapper() de otros paquetes ayuda mucho. Usaremos {ggpubr}

    • Los de reporte: Deben ser elegantes y super personalizados., aunque se demoren en generarse. ¡{ggplot2} es fenomenal para estos!

Histogramas de frecuencias

Podemos crear histogramas usando la geometría geom_histogram().

bd_inmuno %>% 
  ggplot(aes(x = IgG_Basal)) + 
  geom_histogram()
`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

Se puede configurar el ancho de las barras (bins e inglés).

bd_inmuno %>% 
  ggplot(aes(x = IgG_Basal)) + 
  geom_histogram(binwidth = 5) 

bd_inmuno %>% 
  ggplot(aes(x = IgG_Basal)) + 
  geom_histogram(binwidth = 50) 

bd_inmuno %>% 
  ggplot(aes(x = IgG_Basal)) + 
  geom_histogram(binwidth = 200) 

Podemos personalizar el gráfico agregando capas. Por ejemplo, podemos usar labs() y theme_:

bd_inmuno %>% 
  ggplot(aes(x = IgG_Basal)) + 
  geom_histogram(binwidth = 5) + 
  labs(x = "Ig G al inicio del estudio", 
       y = "Frecuencia", 
       title = "Distribución de la IgG") + 
  theme_bw()



Más información en el siguiente enlace:

https://ggplot2.tidyverse.org/reference/geom_histogram.html

Histogramas de densidades

Podemos usar densidades en vez de frecuencias absolutas o relativas en los histogramas. En variables continuas, las densidades se aproximan mejor a la idea de densidad de probabilidad

bd_inmuno %>% 
  ggplot(aes(x = IgG_Basal)) + 
  geom_histogram(aes(y = ..density..))
`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

Se puede configurar el ancho de las barras (bins e inglés).

bd_inmuno %>% 
  ggplot(aes(x = IgG_Basal)) + 
  geom_histogram(aes(y = ..density..), 
                 binwidth = 5)

bd_inmuno %>% 
  ggplot(aes(x = IgG_Basal)) + 
  geom_histogram(aes(y = ..density..), 
                 binwidth = 50)

bd_inmuno %>% 
  ggplot(aes(x = IgG_Basal)) + 
  geom_histogram(aes(y = ..density..), 
                 binwidth = 200)

Podemos personalizar el gráfico agregando capas. Por ejemplo, podemos usar labs() y theme_:

bd_inmuno %>% 
  ggplot(aes(x = IgG_Basal)) + 
  geom_histogram(aes(y = ..density..), binwidth = 5) + 
  labs(x = "Ig G al inicio del estudio", 
       y = "Frecuencia", 
       title = "Distribución de la IgG") + 
  theme_bw()



Más información en el siguiente enlace:

https://ggplot2.tidyverse.org/reference/geom_histogram.html

Densidad

En vez de graficar histogramas, podemos dibujar gráfico de densidades cuyas curvas están suavizadas imitando el aspecto de una distribución de probabilidad. Usamo la geometría geom_density().

bd_inmuno %>% 
  ggplot(aes(x = IgG_Basal)) + 
  geom_density()

Se puede configurar el parámetro de suavización adjust

bd_inmuno %>% 
  ggplot(aes(x = IgG_Basal)) + 
  geom_density(adjust = 0.1)

bd_inmuno %>% 
  ggplot(aes(x = IgG_Basal)) + 
  geom_density(adjust = 0.5)

bd_inmuno %>% 
  ggplot(aes(x = IgG_Basal)) + 
  geom_density(adjust = 2)

Podemos personalizar el gráfico agregando capas. Por ejemplo, podemos usar labs() y theme_:

bd_inmuno %>% 
  ggplot(aes(x = IgG_Basal)) + 
  geom_density(adjust = 1) + 
  labs(x = "Ig G al inicio del estudio", 
       y = "Densidad", 
       title = "Distribución de la IgG") + 
  theme_bw()



Más información en el siguiente enlace:

https://ggplot2.tidyverse.org/reference/geom_density.html

Gráfico de cajas

Podemos crear gráficos de cajas usando la geometría geom_boxplot().

Cajas horizontales

bd_inmuno %>% 
  ggplot(aes(x = IgG_Basal)) + 
  geom_boxplot()

Cajas verticales

bd_inmuno %>% 
  ggplot(aes(y = IgG_Basal)) + 
  geom_boxplot()

Podemos personalizar el gráfico agregando capas. Por ejemplo, podemos usar labs() y theme_. También podemos eliminar los números y guiones del eje x usando theme().

bd_inmuno %>% 
  ggplot(aes(y = IgG_Basal)) + 
  geom_boxplot() + 
  labs(x = NULL, 
       y = "IgG basal (AU/mL)", 
       title = "Gráfico de cajas de IgG basal") + 
  theme(axis.ticks.x = element_blank(),
        axis.text.x = element_blank())

  • Anatomía:

    • Bordes de caja: percentil 25 (cuartil 1) y 75 (cuartil 3)

    • Linea horizontal dentro de caja: percentil 50 (cuartil 2 o mediana)

    • Rango intercuartílico (IQR): percentil 75- percentil 25

    • Bigotes: ± 1.5 IQR

    • Puntos fuera de bigotes: Outliers según regla de Tukey

  • Aunque se puede usar en gráficos univariados, no es un muy gráfico para estos fines.

    • ¡Es mejor para realizar comparaciones en análisis bivariados!
  • Los “outliers” o valores extremos son solo referenciales.

  • Las cajas sugieren simetría de distribución, pero no permiten ver la forma directamente:

Distribución simétrica

Distribución asimétrica



Más información en el siguiente enlace:

https://ggplot2.tidyverse.org/reference/geom_boxplot.html

Violin

Gráficos de violin son similares a gráficos de caja, excepto porque también muestran la densidad de probabilidad.

Cajas horizontales

bd_inmuno %>% 
  ggplot(aes(x = 1, y = IgG_Basal)) + 
  geom_violin()

Cajas verticales

bd_inmuno %>% 
  ggplot(aes(x = 1, y = IgG_Basal)) + 
  geom_violin()

Podemos personalizar el gráfico agregando capas. Por ejemplo, podemos usar labs() y theme_. También podemos eliminar los números y guiones del eje x usando theme().

bd_inmuno %>% 
  ggplot(aes(x = 1, y = IgG_Basal)) + 
  geom_violin() + 
  labs(x = NULL, 
       y = "IgG basal (AU/mL)", 
       title = "Gráfico de violin de IgG basal") + 
  theme_bw() + 
  theme(axis.ticks.x = element_blank(),
        axis.text.x = element_blank()) 

  • A menudo se reportan combinado con un gráfico de cajas, puntos o ambos.

  • Los gráficos de violin combinados dan mucha más información, por lo que se debería preferir usar.

  • Contraindicación: Si se cuentan con pocos datos, los gráficos de kernel no son confiables.

Distribución simétrica

Distribución asimétrica



Más información en el siguiente enlace:

https://ggplot2.tidyverse.org/reference/geom_violin.html

Combinación de gráficos

Se sugiere reportar gráficos descriptivos que sean informativos. Estos pueden obtenerse de combinar gráficos existentes. Veremos algunos ejemplos.

Sin personalizar

bd_inmuno %>% 
  ggplot(aes(x = IgG_Basal)) + 
  geom_histogram(aes(y = ..density..)) + 
  geom_density()

Personalizado

bd_inmuno %>% 
  ggplot(aes(x = IgG_Basal)) + 
  geom_histogram(aes(y = ..density..), colour = "black", fill = "white") + 
  geom_density(fill = 4, alpha = 0.25) + 
  theme_minimal()

Sin personalizar

bd_inmuno %>% 
  ggplot(aes(x = 1, y = IgG_Basal)) + 
  geom_boxplot() + 
  geom_dotplot(binaxis = "y", stackdir = "center") 

Personalizado

bd_inmuno %>% 
  ggplot(aes(x = 1, y = IgG_Basal)) + 
  geom_boxplot() + 
  geom_dotplot(binaxis = "y", stackdir = "center") + 
  labs(x = NULL, y = "IgG basal (AU/ml)") + 
  theme_minimal() + 
  theme(axis.ticks.x = element_blank(),
        axis.text.x = element_blank()) 

Sin personalizar

bd_inmuno %>% 
  ggplot(aes(x = 1, y = IgG_Basal)) + 
  geom_boxplot() +
  geom_jitter()

Personalizado

bd_inmuno %>% 
  ggplot(aes(x = 1, y = IgG_Basal)) + 
  geom_boxplot() +
  geom_jitter() + 
  labs(x = NULL, y = "IgG basal (AU/ml)") + 
  theme_bw() + 
  theme(axis.ticks.x = element_blank(),
        axis.text.x = element_blank()) 

Sin personalizar

bd_inmuno %>% 
  ggplot(aes(x = 1, y = IgG_Basal)) + 
  geom_violin() +
  geom_boxplot(width = 0.1)

Personalizado

bd_inmuno %>% 
  ggplot(aes(x = 1, y = IgG_Basal)) + 
  geom_violin() +
  geom_boxplot(width = 0.1) + 
  labs(x = NULL, y = "IgG basal (AU/ml)") + 
  theme_bw() + 
  theme(axis.ticks.x = element_blank(),
        axis.text.x = element_blank()) 

Sin personalizar

bd_inmuno %>% 
  ggplot(aes(x = 1, y = IgG_Basal)) + 
  geom_violin() +
  geom_boxplot(width = 0.1, outlier.color = "white") + 
  geom_jitter()

Personalizado

bd_inmuno %>% 
  ggplot(aes(x = 1, y = IgG_Basal)) + 
  geom_violin() +
  geom_boxplot(width = 0.1, outlier.color = "white") + 
  geom_jitter(color = "blue") + 
  labs(x = NULL, y = "IgG basal (AU/ml)") + 
  theme_bw() + 
  theme(axis.ticks.x = element_blank(),
        axis.text.x = element_blank()) 

Gráficas de variables categóricas con R

Agenda

  1. Medidas de resumen para variables numéricas

  2. Análisis descriptivo de variables categóricas

  3. Medidas de resumen de variables categóricas con R

  4. Gráficos de variables numéricas con R

  5. Gráficas de variables categóricas con R

  6. Gráfico de barras

  7. Otros gráficos

¿Qué graficos podemos hacer para visualizar variables categóricas?

  • Se pueden hacer una infinidad de estos.

  • El más común para investigación científica es el gráfico de barras.

  • Una gráfico menos usado en investigación científica, pero sí en reportes o presentaciones podría ser el gráfico de pái.

  • Otros gráficos interesantes:

Gráfico de barras

Agenda

  1. Medidas de resumen para variables numéricas

  2. Análisis descriptivo de variables categóricas

  3. Medidas de resumen de variables categóricas con R

  4. Gráficos de variables numéricas con R

  5. Gráficas de variables categóricas con R

  6. Gráfico de barras

  7. Otros gráficos

Estructura de datos para gráfico de barras


Datos individuales:
geom_bar()
vs.
Datos agrupados:
geom_bar(stat = “identity”) o
geom_col()

Gráfico de barras de frecuencias absolutas

Para estos gráficos vamos a trabajar con los datos de pacientes hospitalizados durante una pandemia de Ébola. Los datos pertenecen al libro The Epidemiologist Handbook descrito en la sección del Syllabus.

  • Importamos y exploramos los datos que están en formato de R: *.rds
ebola_data <- import("linelist_cleaned.rds")
ebola_data %>% 
  glimpse()
Rows: 5,888
Columns: 30
$ case_id              <chr> "5fe599", "8689b7", "11f8ea", "b8812a", "893f25",…
$ generation           <dbl> 4, 4, 2, 3, 3, 3, 4, 4, 4, 4, 4, 4, 6, 5, 6, 9, 1…
$ date_infection       <date> 2014-05-08, NA, NA, 2014-05-04, 2014-05-18, 2014…
$ date_onset           <date> 2014-05-13, 2014-05-13, 2014-05-16, 2014-05-18, …
$ date_hospitalisation <date> 2014-05-15, 2014-05-14, 2014-05-18, 2014-05-20, …
$ date_outcome         <date> NA, 2014-05-18, 2014-05-30, NA, 2014-05-29, 2014…
$ outcome              <chr> NA, "Recover", "Recover", NA, "Recover", "Recover…
$ gender               <chr> "m", "f", "m", "f", "m", "f", "f", "f", "m", "f",…
$ age                  <dbl> 2, 3, 56, 18, 3, 16, 16, 0, 61, 27, 12, 42, 19, 7…
$ age_unit             <chr> "years", "years", "years", "years", "years", "yea…
$ age_years            <dbl> 2, 3, 56, 18, 3, 16, 16, 0, 61, 27, 12, 42, 19, 7…
$ age_cat              <fct> 0-4, 0-4, 50-69, 15-19, 0-4, 15-19, 15-19, 0-4, 5…
$ age_cat5             <fct> 0-4, 0-4, 55-59, 15-19, 0-4, 15-19, 15-19, 0-4, 6…
$ hospital             <chr> "Other", "Missing", "St. Mark's Maternity Hospita…
$ lon                  <dbl> -13.21574, -13.21523, -13.21291, -13.23637, -13.2…
$ lat                  <dbl> 8.468973, 8.451719, 8.464817, 8.475476, 8.460824,…
$ infector             <chr> "f547d6", NA, NA, "f90f5f", "11f8ea", "aec8ec", "…
$ source               <chr> "other", NA, NA, "other", "other", "other", "othe…
$ wt_kg                <dbl> 27, 25, 91, 41, 36, 56, 47, 0, 86, 69, 67, 84, 68…
$ ht_cm                <dbl> 48, 59, 238, 135, 71, 116, 87, 11, 226, 174, 112,…
$ ct_blood             <dbl> 22, 22, 21, 23, 23, 21, 21, 22, 22, 22, 22, 22, 2…
$ fever                <chr> "no", NA, NA, "no", "no", "no", NA, "no", "no", "…
$ chills               <chr> "no", NA, NA, "no", "no", "no", NA, "no", "no", "…
$ cough                <chr> "yes", NA, NA, "no", "yes", "yes", NA, "yes", "ye…
$ aches                <chr> "no", NA, NA, "no", "no", "no", NA, "no", "no", "…
$ vomit                <chr> "yes", NA, NA, "no", "yes", "yes", NA, "yes", "ye…
$ temp                 <dbl> 36.8, 36.9, 36.9, 36.8, 36.9, 37.6, 37.3, 37.0, 3…
$ time_admission       <chr> NA, "09:36", "16:48", "11:22", "12:60", "14:13", …
$ bmi                  <dbl> 117.18750, 71.81844, 16.06525, 22.49657, 71.41440…
$ days_onset_hosp      <dbl> 2, 1, 2, 2, 1, 1, 2, 1, 1, 2, 2, 2, 1, 0, 2, 0, 1…
  • Distribución de pacientes según hospital tabyl()
ebola_data %>% 
  tabyl(hospital)
                             hospital    n    percent
                     Central Hospital  454 0.07710598
                    Military Hospital  896 0.15217391
                              Missing 1469 0.24949049
                                Other  885 0.15030571
                        Port Hospital 1762 0.29925272
 St. Mark's Maternity Hospital (SMMH)  422 0.07167120
  • Distribución de pacientes sin datos faltantes tabyl()
ebola_data %>% 
  filter(hospital != "Missing") %>% 
  tabyl(hospital)
                             hospital    n    percent
                     Central Hospital  454 0.10273818
                    Military Hospital  896 0.20276081
                                Other  885 0.20027155
                        Port Hospital 1762 0.39873274
 St. Mark's Maternity Hospital (SMMH)  422 0.09549672

Usamos geom_bar() cuando queremos que la altura de la barra refleje el número de filas relevantes en los datos. Por defecto, las barras son de frecuencias absolutas y se llaman count.

Barplot vertical

ebola_data %>% 
  ggplot(aes(x = hospital)) + 
  geom_bar()

Barplot horizontal

ebola_data %>% 
  ggplot(aes(y = hospital)) + 
  geom_bar()

Usamos geom_col() cuando queremos que la altura de la barra refleje valores pre-calculados que existen en los datos. A menudo, los datos son agregads y pueden obtenerse mediante la combinación summarise() y group_by().

  • Te proprocionan una tabla de datos agregada (no tienes valores individuales), solo los totales de casos y6 su prevalencia:
  nivel_dolor casos prevalencia
1        Leve   234        61.9
2    Moderado   123        32.5
3      Severo    21         5.6
  • Puedes graficarlo usando geom_col() que no requiere datos individuales.
datos_agregados %>% 
  ggplot(aes(x = nivel_dolor, y = casos)) + 
  geom_col()

geom_col() y geom_bar() son equivalentes.

datos_agregados %>% 
  ggplot(aes(x = nivel_dolor, y = casos)) + 
  geom_col()

datos_agregados %>% 
  ggplot(aes(x = nivel_dolor, y = casos)) + 
  geom_bar(stat = "identity")

Si tenemos datos individuales, podemos agregarlos y así resulta más fácil pensar en los gráficos de barras desde ggplot()

ebola_data %>% 
  group_by(hospital) %>% 
  count() %>% 
  ggplot(aes(x = n, y = hospital)) + 
  geom_col()

ebola_data %>% 
  group_by(hospital) %>% 
  count() %>% 
  ggplot(aes(x = n, y = hospital)) + 
  geom_bar(stat = "identity")

Cambiar el orden de las barras arbitrariamente

ebola_data %>% 
  mutate(
    hospital = fct_relevel(hospital, 
                           "St. Mark's Maternity Hospital (SMMH)", 
                           "Port Hospital", 
                           "Central Hospital",
                           "Military Hospital",
                           "Other",
                           "Missing")
    ) %>% 
  ggplot(aes(y = hospital)) + 
  geom_bar()

Editar etiquetas y tema

ebola_data %>% 
  mutate(
    hospital = fct_relevel(hospital, 
                           "St. Mark's Maternity Hospital (SMMH)", "Port Hospital", 
                           "Central Hospital", "Military Hospital", "Other",
                           "Missing")
    ) %>% 
  ggplot(aes(y = hospital)) + 
  geom_bar() + 
  labs(x = "Frecuencia absoluta", y = "Hospitales") + 
  theme_bw()

Gráfico de barras de frecuencias relativas

Las frecuencias relativas necesitan ser calculadas para reportarse. La forma más fácil de hacerlo es agregando los datos mediante el uso de count(). Luego usamos mutate() para crear las proporciones o porcentajes. También podemos trabajar con datos individuales, pero el código puede verse un poco más duro.

  • Agregamos los datos de hospitalizados
ebola_data %>% 
  count(hospital)
                              hospital    n
1                     Central Hospital  454
2                    Military Hospital  896
3                              Missing 1469
4                                Other  885
5                        Port Hospital 1762
6 St. Mark's Maternity Hospital (SMMH)  422
  • Creamos la columna de porcentaje:
ebola_data %>% 
  count(hospital) %>% 
  mutate(porcentaje = 100 * n / sum(n))
                              hospital    n porcentaje
1                     Central Hospital  454   7.710598
2                    Military Hospital  896  15.217391
3                              Missing 1469  24.949049
4                                Other  885  15.030571
5                        Port Hospital 1762  29.925272
6 St. Mark's Maternity Hospital (SMMH)  422   7.167120

Podemos usar geom_bar() con datos agregados y no agregados para obtener prorporciones. El código puede ser un poco más “extraño” con datos individuales, pero la idea es copiar/pegar y adaptar.

Agregando datos

ebola_data %>% 
  count(hospital) %>% 
  mutate(porcentaje = 100 * n / sum(n)) %>% 
  ggplot(aes(x = hospital, y = porcentaje)) + 
  geom_bar(stat = "identity")

Con datos individuales

ebola_data %>% 
  ggplot(aes(x = hospital)) + 
  geom_bar(aes(y = (..count..)/sum(..count..)))

Orden por defecto

ebola_data %>% 
  count(hospital) %>% 
  mutate(porcentaje = 100 * n / sum(n)) %>% 
  ggplot(aes(x = hospital, y = porcentaje)) + 
  geom_col()

Orden arbitrario

ebola_data %>% 
  mutate(
    hospital = fct_relevel(hospital, 
                           "St. Mark's Maternity Hospital (SMMH)", 
                           "Port Hospital", 
                           "Central Hospital",
                           "Military Hospital",
                           "Other",
                           "Missing")
    ) %>% 
  count(hospital) %>% 
  mutate(porcentaje = 100 * n / sum(n)) %>% 
  ggplot(aes(x = hospital, y = porcentaje)) + 
  geom_col()

Podemos querer reordenar las barras de mayor a menoro o viceversa. geom_col() y geom_bar() tiene su propia forma de hacerlo.

Reordenar con geom_bar()

ebola_data %>% 
  ggplot(aes(x = fct_infreq(hospital))) + 
  geom_bar()

Reordenar con geom_col()

ebola_data %>% 
  group_by(hospital) %>% 
  count() %>% 
  ggplot(aes(x = n, y = fct_reorder(hospital, n))) + 
  geom_col()

Podemos etiquetar los gráficos usando la función labs() y sus argumentos.

ebola_data %>% 
  count(hospital) %>% 
  mutate(porcentaje = n / sum(n)) %>% 
  ggplot(aes(x = porcentaje, y = fct_reorder(hospital, porcentaje))) + 
  geom_col() + 
  labs(x = "Porcentaje (%)", 
       y = "Hospital", 
       title = "Distribución de hospitalizaciones de pacientes de Ébola")

También podemos hacer que los colores cambien en base a alguna otra variable

ebola_data %>% 
  count(hospital) %>% 
  mutate(porcentaje = n / sum(n)) %>% 
  ggplot(aes(x = porcentaje, 
             y = fct_reorder(hospital, porcentaje), 
             fill = hospital)) + 
  geom_col() + 
  labs(x = "Porcentaje (%)", 
       y = "Hospital", 
       title = "Distribución de hospitalizaciones de pacientes de Ébola", 
       fill = "Hospital") 

Podemos eliminar la leyenda fácilmente con una capa adicional llamada theme(legend.position=“none”)

ebola_data %>% 
  count(hospital) %>% 
  mutate(porcentaje = n / sum(n)) %>% 
  ggplot(aes(x = porcentaje, 
             y = fct_reorder(hospital, porcentaje), 
             fill = hospital)) + 
  geom_col() + 
  labs(x = "Porcentaje (%)", 
       y = "Hospital", 
       title = "Distribución de hospitalizaciones de pacientes de Ébola", 
       fill = "Hospital")  + 
  theme(legend.position = "none")

Otros gráficos

Agenda

  1. Medidas de resumen para variables numéricas

  2. Análisis descriptivo de variables categóricas

  3. Medidas de resumen de variables categóricas con R

  4. Gráficos de variables numéricas con R

  5. Gráficas de variables categóricas con R

  6. Gráfico de barras

  7. Otros gráficos

Gráfico de barras apilada

En vez de graficar varias barras de manera horizontal, las apilamos todas en una sola barra.

Grafico de barras apiladas de frecuencias absolutas

ebola_data %>% 
  count(hospital) %>% 
  ggplot(aes(x = "", y = n, fill = hospital)) + 
  geom_bar(stat = "identity", position = "stack")

Grafico de barras apiladas de frecuencias relativas

ebola_data %>% 
  count(hospital) %>% 
  ggplot(aes(x = "", y = n, fill = hospital)) + 
  geom_bar(stat = "identity", position = "fill")

Gráfico de pie

Es un gráfico de barras empaquetado como una torta o pái; por lo que el código en ggplot primero crea el gráfico de barras y luego lo convierte en torta.

Grafico de barras apiladas de frecuencias absolutas

ebola_data %>% 
  count(hospital) %>% 
  ggplot(aes(x = "", y = n, fill = hospital)) + 
  geom_bar(stat = "identity", width = 1) + 
  coord_polar("y", start = 0)

Grafico de barras apiladas de frecuencias relativas

ebola_data %>% 
  count(hospital) %>% 
  ggplot(aes(x = "", y = n, fill = hospital)) + 
  geom_bar(stat = "identity", position = "fill", width = 1) + 
  coord_polar("y", start = 0)

Lollipop plot

Gráficos que parecen chupetines (“lollipop”). Son equivalentes a las barras. Pueden usarse también para describir la distribución de variables numéricas discretas y deberían preferirse a los histogramas en este caso.

ebola_data %>% 
  count(hospital) %>% 
  ggplot(aes(x = hospital, y = n)) + 
  geom_segment(aes(x = hospital, xend = hospital, y = 0, yend = n)) + 
  geom_point() + 
  theme_minimal()

ebola_data %>% 
  count(hospital) %>% 
  ggplot(aes(x = hospital, y = n)) + 
  geom_segment(aes(x = hospital, xend = hospital, y = 0, yend = n), color = "skyblue") + 
  geom_point(color = "blue", alpha = 0.6, size = 4) + 
  theme_light() + 
  coord_flip() + 
  theme(
  panel.grid.major.y = element_blank(),
  panel.border = element_blank(),
  axis.ticks.y = element_blank()
  )

Treemap

Es un gráfico básico que muestra mosaicos. El área de cada polígono refleja su frecuencia absoluta o relativa. Se debe usar el paquete {treemap}

library(treemap)
ebola_data %>% 
  count(hospital) %>% 
  treemap(index = "hospital", 
          vSize = "n", 
          type = "index")

Más gráficos

Revisar la web “The R Graph Gallery”:

Ver más: https://r-graph-gallery.com/index.html

Hagamos una pausa


Tomemos un descanso de 5 minutos

Estire las piernas

Deje de ver las pantallas

… cualquier , las del celular también.

05:00

¡Gracias!
¿Preguntas?




@psotob91

https://github.com/psotob91

percys1991@gmail.com